package cn.conac.rc.framework.utils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;

/**
 * 公共entity、service、repository自动生成工具带注解（关联关系需要手动添加）</br>
 * 执行前请确认 </br>
 * 1、db链接是否正确</br>
 * 2、tablename的填写 </br>
 * 3、package基本路径 </br>
 * 确认以上三步后，致敬运行此java，执行后 生成的文件在target根目录，将文件拷贝到已经创建好的资源文件目录中。
 * @author haocm
 */
public class AutoDaoTool {

    public static final char UNDERLINE = '_';
    private static final String DATA_TABLE = "1";
    private static final String BASE_TABLE = "2";

    private static String dbConfig = "/config.properties";

    /** 
     * 默认改修Table的类型为DATAEntity继承类。
     * 如需生成BASEEntity的继承类将下面值修改为BASE_TABLE即可。
     */
    //private String tableType = DATA_TABLE;
     private String tableType = BASE_TABLE;

    private String[] data_tables = {
            "RC_AREA",
            "RC_PERMISSION",
            "RC_ROLE",
            "RC_ROLE_PERMISSION",
            "RC_USER",
            "RC_USER_ROLE"
	};
    private String[] base_tables = {
    	"RCO_V_ORGS_COMP_QUERY"
//		"RCO_INST_ORG_IMPORT",
//		"RCO_ORG_INFO_IMPORT",
//		"RC_ROLE_PERMISSION",
//		"RC_USER_ROLE",
//		"RCO_APPROVAL_FILES",
//		"RCO_DEPART_DUTY"
    };
    private String[] voColName = {
		"page",
		"size",
		"createDateStart",
		"createDateEnd",
		"updateDateStart",
		"updateDateEnd"
    };
    private String[] voColComments = {
		"当前分页",
		"每页个数",
		"创建 开始时间",
		"创建 结束时间",
		"更新 开始时间",
		"更新 结束时间"
    };
    private String[] voColType = {
		"Integer",
		"Integer",
		"Date",
		"Date",
		"Date",
		"Date",
		"Date"
    };
    //TODO 包名
    private String packageStr = "cn.conac.rc";
    // 注解
    private String annotateApiModel = "@ApiModel";
    private String annotateEntity = "@Entity";
    private String annotateTable = "@Table";
    private String annotateService = "@Service";
    private String annotateController = "@RestController";
    private String annotateRepository = "@Repository";

    public AutoDaoTool() {
        Connection conn = null;
        try {
        	Properties props = new Properties();
        	InputStream in = ClassLoader.class.getResourceAsStream(dbConfig);
        	props.load(in);
            Class.forName(props.getProperty("driver"));
            conn = DriverManager.getConnection(props.getProperty("url"),props);
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        String[] colNames; // 列名数组
        String[] colTypes; // 列名类型数组
        String[] colComments; // 列名类型数组

        for (String tablename : DATA_TABLE.equals(tableType)?data_tables:base_tables) {
            try {
                // String strsql = "select * from " + tablename;
                // String strsql2 = "select * from user_col_comments where
                // Table_Name='" + tablename + "'";
                // PreparedStatement pstmt = conn.prepareStatement(strsql);
                // ResultSetMetaData rsmd = pstmt.getMetaData();
                // int size = rsmd.getColumnCount(); // 共有多少列

                DatabaseMetaData dbmd = conn.getMetaData();
                ResultSet rs = dbmd.getColumns(null, this.getSchema(conn), tablename.toUpperCase(), "%");
                int rowCount = 100;

                colNames = new String[rowCount];
                colTypes = new String[rowCount];
                colComments = new String[rowCount];
                int i = 0;
                while (rs.next()) {
                    System.out.println(underlineToCamel(rs.getString("COLUMN_NAME").toLowerCase()) + "+++++++++++"
                            + rs.getInt("DATA_TYPE") + "+++++++++++" + rs.getString("TYPE_NAME") + "+++++++++++"
                            + rs.getString("REMARKS"));
                    colNames[i] = underlineToCamel(rs.getString("COLUMN_NAME").toLowerCase());
                    colTypes[i] = rs.getString("TYPE_NAME");// 数据类型
                    colComments[i] = rs.getString("REMARKS");
                    i++;
                }
                // for (int i = 0; i < rsmd.getColumnCount(); i++) {
                // colNames[i] = underlineToCamel(rsmd.getColumnName(i +
                // 1).toLowerCase());
                // colTypes[i] = rsmd.getColumnTypeName(i + 1);
                //
                // if (colTypes[i].equalsIgnoreCase("date")) {
                // f_util = true;
                // }
                // if (colTypes[i].equalsIgnoreCase("image") ||
                // colTypes[i].equalsIgnoreCase("text")) {
                // f_sql = true;
                // }
                // colSizes[i] = rsmd.getColumnDisplaySize(i + 1);
                // }
                String[] newcolNames = new String[rowCount];
            	String[] newcolComments = new String[rowCount];
            	String[] newcolTypes = new String[rowCount];
                this.removeNormalColumn(colNames, colComments, colTypes, newcolNames, newcolComments, newcolTypes);// 去除常用字段以及注释,字段类型
                String content = parse(tablename, newcolNames, newcolTypes, newcolComments);
                tablename = this.removeRcoOrRc(tablename);
                String contentVo = parseVo(tablename, voColName, voColType, voColComments);
                String contentService = parseService(tablename);
                String contentController = parseController(tablename);
                String contentrepository = parseRepository(tablename);
                // entity文件名
                String entityName = underlineToCamel("entity/" + initcap(tablename.toLowerCase()) + "Entity");
                // vo文件名
                String entityVo = underlineToCamel("vo/" + initcap(tablename.toLowerCase()) + "Vo");
                // service文件名
                String serviceName = underlineToCamel("service/" + initcap(tablename.toLowerCase()) + "Service");
                // controller文件名
                String controllerName = underlineToCamel("rest/" + initcap(tablename.toLowerCase()) + "Controller");
                // repository文件名
                String repositoryName = underlineToCamel("repository/" + initcap(tablename.toLowerCase()) + "Repository");
                // 生成entity文件
                printWriter(content, entityName);
                // 生成vo文件
                printWriter(contentVo, entityVo);
                // 生成service文件
                printWriter(contentService, serviceName);
                // 生成controller文件
                printWriter(contentController, controllerName);
                // 生成repository文件
                printWriter(contentrepository, repositoryName);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

    private static void printWriter(String content, String name) {
        try {
            FileUtils.write(new File(name + ".java"), content, "UTF8");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 解析处理(生成实体类主体代码)
     */
    private String parse(String tablename, String[] colNames, String[] colTypes, String[] comments) {
        StringBuffer sb = new StringBuffer();
        sb.append("package " + packageStr + ".entity;\r\n\r\n");

        sb.append("import java.io.Serializable;\r\n");
        sb.append("import java.util.Date;\r\n\r\n");

        sb.append("import javax.persistence.Entity;\r\n");
        sb.append("import javax.persistence.Table;\r\n\r\n");

        if(BASE_TABLE.equals(tableType)){
        	sb.append("import cn.conac.rc.framework.entity.BaseEntity;\r\n");
        } else if(DATA_TABLE.equals(tableType)){
        	sb.append("import cn.conac.rc.framework.entity.DataEntity;\r\n");
        }
        sb.append("import io.swagger.annotations.ApiModel;\r\n");
        sb.append("import io.swagger.annotations.ApiModelProperty;\r\n\r\n");

        sb.append(annotateApiModel + "\r\n");
        sb.append(annotateEntity + "\r\n");
        sb.append(annotateTable + "(name=\"" + tablename + "\")" + "\r\n");
        sb.append("public class " + initcap(underlineToCamel(this.removeRcoOrRc(tablename).toLowerCase())) + "Entity");
        if(BASE_TABLE.equals(tableType)){
        	sb.append(" extends BaseEntity<" + initcap(underlineToCamel(this.removeRcoOrRc(tablename).toLowerCase())) + "Entity> implements Serializable {\r\n\r\n");
        } else if(DATA_TABLE.equals(tableType)){
        	sb.append(" extends DataEntity<" + initcap(underlineToCamel(this.removeRcoOrRc(tablename).toLowerCase())) + "Entity> implements Serializable {\r\n\r\n");
        }
        sb.append("\tprivate static final long serialVersionUID = " + System.currentTimeMillis() + Math.round(Math.random()*1000000) + "L;\r\n\r\n");
        
        processAllAttrs(sb, colNames, colTypes, comments);
        processAllMethod(sb, colNames, colTypes);
        sb.append("}\r\n");
        System.out.println(sb.toString());
        return sb.toString();

    }

    /**
     * 解析处理(生成VO类主体代码)
     */
    private String parseVo(String tablename, String[] colNames, String[] colTypes, String[] comments) {
        StringBuffer sb = new StringBuffer();
        sb.append("package " + packageStr + ".vo;\r\n\r\n");

        sb.append("import java.util.Date;\r\n\r\n");

        sb.append("import javax.persistence.Transient;\r\n\r\n");

        sb.append("import " + packageStr + ".entity." + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity;\r\n");
        sb.append("import io.swagger.annotations.ApiModel;\r\n");
        sb.append("import io.swagger.annotations.ApiModelProperty;\r\n\r\n");

        sb.append(annotateApiModel + "\r\n");
        sb.append("public class " + initcap(underlineToCamel(tablename.toLowerCase())) + "Vo extends " + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity {\r\n\r\n");
        sb.append("\tprivate static final long serialVersionUID = " + System.currentTimeMillis() + Math.round(Math.random()*1000000) + "L;\r\n\r\n");
        
        processAllAttrs2(sb, colNames, colTypes, comments);
        processAllMethod2(sb, colNames, colTypes);
        sb.append("}\r\n");
        System.out.println(sb.toString());
        return sb.toString();

    }

    /**
     * 解析输出属性
     * @return
     */
    private void processAllAttrs2(StringBuffer sb, String[] colNames, String[] colTypes, String[] comments) {
        for (int i = 0; i < colNames.length; i++) {
            if (colNames[i] == null){
            	return;
            }
            sb.append("\t@Transient\r\n");
            sb.append("\t" + "@ApiModelProperty(\"" + comments[i] + "\")" + "\r\n");
            sb.append("\tprivate " + colTypes[i] + " " + colNames[i] + ";\r\n\r\n");
        }
    }

    /**
     * 解析输出属性
     * @return
     */
    private void processAllAttrs(StringBuffer sb, String[] colNames, String[] colTypes, String[] comments) {
        for (int i = 0; i < colNames.length; i++) {
            if (colNames[i] == null)
                return;
            if (comments[i] != null && comments[i].length() > 0)
                sb.append("\t" + "@ApiModelProperty(\"" + comments[i] + "\")" + "\r\n");
            else
                sb.append("\t" + "@ApiModelProperty(\"" + colNames[i] + "\")" + "\r\n");
            sb.append("\tprivate " + sqlType2JavaType(colTypes[i]) + " " + colNames[i] + ";\r\n\r\n");

        }
    }

    /**
     * 将常用字段（ID,CreateUser,UpdateUser等）去除掉
     * @param colnames
     * @param colcomments
     * @param coltypes
     * @param newcol
     * @param newment
     * @param newcolType
     */
    private void removeNormalColumn(String[] colnames, String[] colcomments, String[] coltypes, String[] newcol, String[] newment, String[] newcolType){
		List<String> newcolnames = new ArrayList<String>();
		List<String> newcolcomments = new ArrayList<String>();
		List<String> newcolTypes = new ArrayList<String>();
		if(colnames != null){

			for(int i=0; i<colnames.length; i++){
				if(!"id".equals(colnames[i]) &&
						!"createDate".equals(colnames[i]) &&
						!"createUser".equals(colnames[i]) &&
						!"updateDate".equals(colnames[i]) &&
						!"updateUser".equals(colnames[i]) &&
						!"deleteMark".equals(colnames[i]) &&
						!"remarks".equals(colnames[i])){
					newcolnames.add(colnames[i]);
					newcolcomments.add(colcomments[i]);
					newcolTypes.add(coltypes[i]);
				}
			}
			
			int i=0;
			for(String col: newcolnames){
				newcol[i] = col;
				i++;
			}
			
			int j=0;
			for(String colcomment: newcolcomments){
				newment[j] = colcomment;
				j++;
			}
			
			int k=0;
			for(String coltype: newcolTypes){
				newcolType[k] = coltype;
				k++;
			}
		}
	}
    
    /**
     * 获取Schema
     * @param conn
     * @return
     * @throws Exception
     */
    private String getSchema(Connection conn) throws Exception {
        String schema;
        schema = conn.getMetaData().getUserName();
        if ((schema == null) || (schema.length() == 0)) {
            throw new Exception("ORACLE数据库模式不允许为空");
        }
        return schema.toUpperCase().toString();
    }

    /**
     * 生成所有的方法
     * @param sb
     */
    private void processAllMethod(StringBuffer sb, String[] colNames, String[] colTypes) {
        for (int i = 0; i < colNames.length; i++) {
            if (colNames[i] == null)
                return;
            sb.append("\tpublic void set" + initcap(colNames[i]) + "(" + sqlType2JavaType(colTypes[i]) + " "
                    + colNames[i] + "){\r\n");
            sb.append("\t\tthis." + colNames[i] + "=" + colNames[i] + ";\r\n");
            sb.append("\t}\r\n\r\n");

            sb.append("\tpublic " + sqlType2JavaType(colTypes[i]) + " get" + initcap(colNames[i]) + "(){\r\n");
            sb.append("\t\treturn " + colNames[i] + ";\r\n");
            sb.append("\t}\r\n\r\n");
        }
    }

    /**
     * 生成所有的方法
     * @param sb
     */
    private void processAllMethod2(StringBuffer sb, String[] colNames, String[] colTypes) {
        for (int i = 0; i < colNames.length; i++) {
            if (colNames[i] == null)
                return;
            sb.append("\tpublic void set" + initcap(colNames[i]) + "(" + (colTypes[i]) + " "
                    + colNames[i] + "){\r\n");
            sb.append("\t\tthis." + colNames[i] + "=" + colNames[i] + ";\r\n");
            sb.append("\t}\r\n\r\n");

            sb.append("\tpublic " + colTypes[i] + " get" + initcap(colNames[i]) + "(){\r\n");
            sb.append("\t\treturn " + colNames[i] + ";\r\n");
            sb.append("\t}\r\n\r\n");
        }
    }

    /**
     * 解析处理(生成Service类主体代码)
     */
    private String parseService(String tablename) {
        StringBuffer sb = new StringBuffer();
        sb.append("package " + packageStr + ".service;\r\n\r\n");

        sb.append("import org.springframework.beans.factory.annotation.Autowired;\r\n");
        sb.append("import org.springframework.data.domain.Page;\r\n");
        sb.append("import org.springframework.data.domain.PageRequest;\r\n");
        sb.append("import org.springframework.data.domain.Pageable;\r\n");
        sb.append("import org.springframework.data.domain.Sort;\r\n");
        sb.append("import org.springframework.data.domain.Sort.Direction;\r\n");
        sb.append("import org.springframework.stereotype.Service;\r\n\r\n");

        sb.append("import " + packageStr + ".entity." + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity;\r\n");
        sb.append("import " + packageStr + ".repository." + initcap(underlineToCamel(tablename.toLowerCase())) + "Repository;\r\n");
        sb.append("import " + packageStr + ".vo." + initcap(underlineToCamel(tablename.toLowerCase())) + "Vo;\r\n");
        sb.append("import cn.conac.rc.framework.jpa.Criteria;\r\n");
        sb.append("import cn.conac.rc.framework.service.GenericService;\r\n\r\n");

        sb.append(annotateService + "\r\n");
        sb.append("public class " + initcap(underlineToCamel(tablename.toLowerCase())) + "Service extends GenericService<"
                        + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity, String> {\r\n\r\n");
        
        sb.append("\t@Autowired\r\n");
        sb.append("\tprivate " + initcap(underlineToCamel(tablename.toLowerCase())) + "Repository repository;\r\n\r\n");

        sb.append("\t/**\r\n");
        sb.append("\t * 计数查询\r\n");
        sb.append("\t * @param vo\r\n");
        sb.append("\t * @return 计数结果\r\n");
        sb.append("\t */\r\n");
        sb.append("\tpublic long count(" + initcap(underlineToCamel(tablename.toLowerCase())) + "Vo vo){\r\n");
        sb.append("\t\treturn super.count(this.createCriteria(vo));\r\n");
        sb.append("\t}\r\n\r\n");

        sb.append("\t/**\r\n");
        sb.append("\t * 动态查询，分页，排序查询\r\n");
        sb.append("\t * @param vo\r\n");
        sb.append("\t * @return Page\r\n");
        sb.append("\t * @throws Exception\r\n");
        sb.append("\t */\r\n");
        sb.append("\tpublic Page<" + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity> list(" + initcap(underlineToCamel(tablename.toLowerCase())) + "Vo vo) throws Exception {\r\n");
        sb.append("\t\ttry {\r\n");
        sb.append("\t\t\tSort sort = new Sort(Direction.ASC, \"id\");// TODO 可选的排序\r\n");
        sb.append("\t\t\tPageable pageable = new PageRequest(vo.getPage(), vo.getSize(), sort);\r\n");
        sb.append("\t\t\tCriteria<" + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity> dc = this.createCriteria(vo);\r\n");
        sb.append("\t\t\treturn repository.findAll(dc, pageable);\r\n");
        sb.append("\t\t} catch (Exception e) {\r\n");
        sb.append("\t\t\te.printStackTrace();\r\n");
        sb.append("\t\t\tthrow e;\r\n");
        sb.append("\t\t}\r\n");
        sb.append("\t}\r\n\r\n");
        
        sb.append("\t/**\r\n");
        sb.append("\t * 逻辑删除\r\n");
        sb.append("\t * @param id\r\n");
        sb.append("\t * @return 删除结果\r\n");
        sb.append("\t */\r\n");
        sb.append("\tpublic int uDelete(String id) {\r\n");
        sb.append("\t\treturn repository.uDelete(id);\r\n");
        sb.append("\t}\r\n\r\n");

        sb.append("\t/**\r\n");
        sb.append("\t * 动态查询条件\r\n");
        sb.append("\t * @param param\r\n");
        sb.append("\t * @return Criteria\r\n");
        sb.append("\t */\r\n");
        sb.append("\tprivate Criteria<" + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity> createCriteria(" 
        		+ initcap(underlineToCamel(tablename.toLowerCase())) + "Vo param) {\r\n");
        sb.append("\t\tCriteria<" + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity> dc = new Criteria<" + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity>();\r\n");
        sb.append("\t\t// TODO 具体条件赋值\r\n\r\n");
        sb.append("\t\treturn dc;\r\n");
        sb.append("\t}\r\n\r\n");
        
        sb.append("}\r\n");
        System.out.println(sb.toString());
        return sb.toString();

    }

    /**
     * 解析处理(生成Controller类主体代码)
     */
    private String parseController(String tablename) {
        StringBuffer sb = new StringBuffer();
        sb.append("package " + packageStr + ".rest;\r\n\r\n");
        
        sb.append("import javax.servlet.http.HttpServletRequest;\r\n");
        sb.append("import javax.servlet.http.HttpServletResponse;\r\n\r\n");
        
        sb.append("import org.springframework.beans.factory.annotation.Autowired;\r\n");
        sb.append("import org.springframework.data.domain.Page;\r\n");
        sb.append("import org.springframework.http.HttpStatus;\r\n");
        sb.append("import org.springframework.http.ResponseEntity;\r\n");
        sb.append("import org.springframework.web.bind.annotation.PathVariable;\r\n");
        sb.append("import org.springframework.web.bind.annotation.RequestBody;\r\n");
        sb.append("import org.springframework.web.bind.annotation.RequestMapping;\r\n");
        sb.append("import org.springframework.web.bind.annotation.RequestMethod;\r\n");
        sb.append("import org.springframework.web.bind.annotation.RestController;\r\n\r\n");

        sb.append("import " + packageStr + ".entity." + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity;\r\n");
        sb.append("import " + packageStr + ".service." + initcap(underlineToCamel(tablename.toLowerCase())) + "Service;\r\n");
        sb.append("import " + packageStr + ".vo." + initcap(underlineToCamel(tablename.toLowerCase())) + "Vo;\r\n");
        sb.append("import cn.conac.rc.framework.vo.ResultPojo;\r\n");
        sb.append("import io.swagger.annotations.ApiOperation;\r\n");
        sb.append("import io.swagger.annotations.ApiParam;\r\n\r\n");
        
        sb.append(annotateController + "\r\n");
        sb.append("@RequestMapping(value=\"" + underlineToCamel(tablename.toLowerCase()) + "/\") // TODO 具体根据情况可以改修\r\n");
        sb.append("public class " + initcap(underlineToCamel(tablename.toLowerCase())) + "Controller {\r\n\r\n");

        sb.append("\t@Autowired" + "\r\n");
        sb.append("\t" + initcap(underlineToCamel(tablename.toLowerCase())) + "Service service;\r\n\r\n");
        
        sb.append("\t@ApiOperation(value = \"详情\", httpMethod = \"GET\", response = " + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity.class, notes = \"根据id获取资源详情\")\r\n");
        sb.append("\t@RequestMapping(value = \"{id}\", method = RequestMethod.GET)\r\n");
        sb.append("\tpublic ResponseEntity<ResultPojo> detail(HttpServletRequest request, HttpServletResponse response,\r\n");
        sb.append("\t\t\t@ApiParam(value = \"id\", required = true) @PathVariable(\"id\") String id) {\r\n");
        sb.append("\t\t// 声明返回结果集\r\n");
        sb.append("\t\tResultPojo result = new ResultPojo();\r\n");
        sb.append("\t\t// service调用\r\n");
        sb.append("\t\t" + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity " + underlineToCamel(tablename.toLowerCase()) + " = service.findById(id);\r\n");
        sb.append("\t\t// 结果集设定\r\n");
        sb.append("\t\tresult.setCode(ResultPojo.CODE_SUCCESS);\r\n");
        sb.append("\t\tresult.setResult(" + underlineToCamel(tablename.toLowerCase()) + ");\r\n");
        sb.append("\t\tresult.setMsg(ResultPojo.MSG_SUCCESS);// TODO 根据具体需求配置返回消息\r\n");
        sb.append("\t\treturn new ResponseEntity<ResultPojo>(result, HttpStatus.OK);\r\n");
        sb.append("\t}\r\n\r\n");
        
        sb.append("\t@ApiOperation(value = \"个数\", httpMethod = \"POST\", response = " + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity.class, notes = \"根据条件获得资源数量\")\r\n");
        sb.append("\t@RequestMapping(value = \"count\", method = RequestMethod.POST)\r\n");
        sb.append("\tpublic ResponseEntity<ResultPojo> count(HttpServletRequest request, HttpServletResponse response,\r\n");
        sb.append("\t\t\t@ApiParam(value = \"查询条件对象\", required = true) @RequestBody " + initcap(underlineToCamel(tablename.toLowerCase())) + "Vo vo) throws Exception {\r\n");
        sb.append("\t\t// 声明返回结果集\r\n");
        sb.append("\t\tResultPojo result = new ResultPojo();\r\n");
        sb.append("\t\t// service调用\r\n");
        sb.append("\t\tlong cnt = service.count(vo);\r\n");
        sb.append("\t\t// 结果集设定\r\n");
        sb.append("\t\tresult.setCode(ResultPojo.CODE_SUCCESS);\r\n");
        sb.append("\t\tresult.setResult(cnt);\r\n");
        sb.append("\t\tresult.setMsg(ResultPojo.MSG_SUCCESS);// TODO 根据具体需求配置返回消息\r\n");
        sb.append("\t\treturn new ResponseEntity<ResultPojo>(result, HttpStatus.OK);\r\n");
        sb.append("\t}\r\n\r\n");
        
        sb.append("\t@ApiOperation(value = \"列表\", httpMethod = \"POST\", response = " + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity.class, notes = \"根据条件获得资源列表\")\r\n");
        sb.append("\t@RequestMapping(value = \"list\", method = RequestMethod.POST)\r\n");
        sb.append("\tpublic ResponseEntity<ResultPojo> list(HttpServletRequest request, HttpServletResponse response,\r\n");
        sb.append("\t\t\t@ApiParam(value = \"查询条件对象\", required = true) @RequestBody " + initcap(underlineToCamel(tablename.toLowerCase())) + "Vo vo) throws Exception {\r\n");
        sb.append("\t\t// 声明返回结果集\r\n");
        sb.append("\t\tResultPojo result = new ResultPojo();\r\n");
        sb.append("\t\t// service调用\r\n");
        sb.append("\t\tPage<" + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity> list = service.list(vo);\r\n");
        sb.append("\t\t// 结果集设定\r\n");
        sb.append("\t\tresult.setCode(ResultPojo.CODE_SUCCESS);\r\n");
        sb.append("\t\tresult.setResult(list);\r\n");
        sb.append("\t\tresult.setMsg(ResultPojo.MSG_SUCCESS);// TODO 根据具体需求配置返回消息\r\n");
        sb.append("\t\treturn new ResponseEntity<ResultPojo>(result, HttpStatus.OK);\r\n");
        sb.append("\t}\r\n\r\n");
        
        sb.append("\t@ApiOperation(value = \"新增\", httpMethod = \"POST\", response = " + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity.class, notes = \"保存资源到数据库\")\r\n");
        sb.append("\t@RequestMapping(value = \"\", method = RequestMethod.POST)\r\n");
        sb.append("\tpublic ResponseEntity<ResultPojo> save(HttpServletRequest request, HttpServletResponse response,\r\n");
        sb.append("\t\t\t@ApiParam(value = \"保存对象\", required = true) @RequestBody " + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity entity) throws Exception {\r\n");
        sb.append("\t\t// 声明返回结果集\r\n");
        sb.append("\t\tResultPojo result = new ResultPojo();\r\n\r\n");
        sb.append("\t\t//TODO 1.用户权限校验\r\n\r\n");
        sb.append("\t\t//TODO 2.数据格式校验\r\n");
        sb.append("\t\tString valMsg = service.validate(entity);\r\n");
        sb.append("\t\tif (valMsg != null) {\r\n");
        sb.append("\t\t\tresult.setCode(ResultPojo.CODE_FORMAT_ERR);\r\n");
        sb.append("\t\t\tresult.setMsg(valMsg);\r\n");
        sb.append("\t\t\treturn new ResponseEntity<ResultPojo>(result, HttpStatus.OK);\r\n");
        sb.append("\t\t}\r\n\r\n");
        sb.append("\t\t//TODO 3.业务逻辑校验\r\n\r\n");
        sb.append("\t\t//TODO 4.业务操作\r\n\r\n");
        sb.append("\t\t// 结果集设定\r\n");
        sb.append("\t\tresult.setCode(ResultPojo.CODE_SUCCESS);\r\n");
        sb.append("\t\tresult.setResult(entity);\r\n");
        sb.append("\t\tresult.setMsg(ResultPojo.MSG_SUCCESS);// TODO 根据具体需求配置返回消息\r\n");
        sb.append("\t\treturn new ResponseEntity<ResultPojo>(result, HttpStatus.OK);\r\n");
        sb.append("\t}\r\n\r\n");
        
        sb.append("\t@ApiOperation(value = \"更新\", httpMethod = \"POST\", response = " + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity.class, notes = \"根据id更新数据库资源\")\r\n");
        sb.append("\t@RequestMapping(value = \"{id}\", method = RequestMethod.POST)\r\n");
        sb.append("\tpublic ResponseEntity<ResultPojo> update(HttpServletRequest request, HttpServletResponse response,\r\n");
        sb.append("\t\t\t@ApiParam(value = \"更新对象\", required = true) @RequestBody " + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity entity) {\r\n");
        sb.append("\t\t// 声明返回结果集\r\n");
        sb.append("\t\tResultPojo result = new ResultPojo();\r\n");
        sb.append("\t\t// service调用\r\n");
        sb.append("\t\tservice.save(entity);\r\n");
        sb.append("\t\t// 结果集设定\r\n");
        sb.append("\t\tresult.setCode(ResultPojo.CODE_SUCCESS);\r\n");
        sb.append("\t\tresult.setResult(entity);\r\n");
        sb.append("\t\tresult.setMsg(ResultPojo.MSG_SUCCESS);// TODO 根据具体需求配置返回消息\r\n");
        sb.append("\t\treturn new ResponseEntity<ResultPojo>(result, HttpStatus.OK);\r\n");
        sb.append("\t}\r\n\r\n");
        
        sb.append("\t@ApiOperation(value = \"物理删除\", httpMethod = \"POST\", response = " + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity.class, notes = \"根据id物理删除资源\")\r\n");
        sb.append("\t@RequestMapping(value = \"{id}/delete\", method = RequestMethod.POST)\r\n");
        sb.append("\tpublic ResponseEntity<ResultPojo> delete(HttpServletRequest request, HttpServletResponse response,\r\n");
        sb.append("\t\t\t@ApiParam(value = \"id\", required = true) @PathVariable(\"id\") String id) {\r\n");
        sb.append("\t\t// 声明返回结果集\r\n");
        sb.append("\t\tResultPojo result = new ResultPojo();\r\n");
        sb.append("\t\t// service调用\r\n");
        sb.append("\t\tservice.delete(id);\r\n");
        sb.append("\t\t// 结果集设定\r\n");
        sb.append("\t\tresult.setCode(ResultPojo.CODE_SUCCESS);\r\n");
        sb.append("\t\tresult.setResult(id);\r\n");
        sb.append("\t\tresult.setMsg(ResultPojo.MSG_SUCCESS);// TODO 根据具体需求配置返回消息\r\n");
        sb.append("\t\treturn new ResponseEntity<ResultPojo>(result, HttpStatus.OK);\r\n");
        sb.append("\t}\r\n\r\n");

        sb.append("\t@ApiOperation(value = \"逻辑删除\", httpMethod = \"POST\", response = " + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity.class, notes = \"根据id逻辑删除资源\")\r\n");
        sb.append("\t@RequestMapping(value = \"{id}/uDelete\", method = RequestMethod.POST)\r\n");
        sb.append("\tpublic ResponseEntity<ResultPojo> uDelete(HttpServletRequest request, HttpServletResponse response,\r\n");
        sb.append("\t\t\t@ApiParam(value = \"id\", required = true) @PathVariable(\"id\") String id) {\r\n");
        sb.append("\t\t// 声明返回结果集\r\n");
        sb.append("\t\tResultPojo result = new ResultPojo();\r\n");
        sb.append("\t\t// service调用\r\n");
        sb.append("\t\tint delNum = service.uDelete(id);\r\n");
        sb.append("\t\t// 结果集设定\r\n");
        sb.append("\t\tif(delNum >0){\r\n");
        sb.append("\t\t\tresult.setCode(ResultPojo.CODE_FAILURE);\r\n");
        sb.append("\t\t\tresult.setResult(id);\r\n");
        sb.append("\t\t\tresult.setMsg(ResultPojo.MSG_FAILURE);// TODO 根据具体需求配置返回消息\r\n");
        sb.append("\t\t} else {\r\n");
        sb.append("\t\t\tresult.setCode(ResultPojo.CODE_SUCCESS);\r\n");
        sb.append("\t\t\tresult.setResult(id);\r\n");
        sb.append("\t\t\tresult.setMsg(ResultPojo.MSG_SUCCESS);// TODO 根据具体需求配置返回消息\r\n");
        sb.append("\t\t}\r\n");
        sb.append("\t\treturn new ResponseEntity<ResultPojo>(result, HttpStatus.OK);\r\n");
        sb.append("\t}\r\n\r\n");

        sb.append("}\r\n");

        System.out.println(sb.toString());
        return sb.toString();

    }

    /**
     * 解析处理(生成Repository类主体代码)
     */
    private String parseRepository(String tablename) {
        StringBuffer sb = new StringBuffer();
        sb.append("package " + packageStr + ".repository;\r\n\r\n");

        sb.append("import org.springframework.data.jpa.repository.Modifying;\r\n");
        sb.append("import org.springframework.data.jpa.repository.Query;\r\n");
        sb.append("import org.springframework.data.repository.query.Param;\r\n");
        sb.append("import org.springframework.stereotype.Repository;\r\n\r\n");

        sb.append("import " + packageStr + ".entity." + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity;\r\n");
        sb.append("import cn.conac.rc.framework.repository.GenericDao;\r\n\r\n");

        sb.append(annotateRepository + "\r\n");
        sb.append("public interface " + initcap(underlineToCamel(tablename.toLowerCase()))
                + "Repository extends GenericDao<" + initcap(underlineToCamel(tablename.toLowerCase()))
                + "Entity, String> {\r\n\r\n");

        sb.append("\t/**\r\n");
        sb.append("\t * 逻辑删除\r\n");
        sb.append("\t * @param id\r\n");
        sb.append("\t * @return 删除数量\r\n");
        sb.append("\t */\r\n");
        sb.append("\t@Query(\"update " + initcap(underlineToCamel(tablename.toLowerCase())) + "Entity a set a.deleteMark=1 where a.id=?1\")\r\n");
        sb.append("\t@Modifying\r\n");
        sb.append("\tint uDelete(@Param(\"id\") String id);\r\n");
        sb.append("}\r\n");

        System.out.println(sb.toString());
        return sb.toString();

    }

    /**
     * 把输入字符串的首字母改成大写
     * @param str
     * @return
     */
    private String initcap(String str) {
        char[] ch = str.toCharArray();
        if (ch[0] >= 'a' && ch[0] <= 'z') {
            ch[0] = (char) (ch[0] - 32);
        }
        return new String(ch);
    }

    private String sqlType2JavaType(String sqlType) {
        if (sqlType.equalsIgnoreCase("tinyint")) {
            return "Integer";
        } else if (sqlType.equalsIgnoreCase("smallint")) {
            return "Integer";
        } else if (sqlType.equalsIgnoreCase("int") || sqlType.equalsIgnoreCase("NUMBER")) {
            return "Integer";
        } else if (sqlType.equalsIgnoreCase("bigint")) {
            return "Long";
        } else if (sqlType.equalsIgnoreCase("float")) {
            return "float";
        } else if (sqlType.equalsIgnoreCase("decimal") || sqlType.equalsIgnoreCase("numeric")
                || sqlType.equalsIgnoreCase("real")) {
            return "Double";
        } else if (sqlType.equalsIgnoreCase("money") || sqlType.equalsIgnoreCase("smallmoney")) {
            return "Double";
        } else if (sqlType.equalsIgnoreCase("varchar") || sqlType.equalsIgnoreCase("char")
                || sqlType.equalsIgnoreCase("nvarchar") || sqlType.equalsIgnoreCase("nvarchar2")
                || sqlType.equalsIgnoreCase("VARCHAR2") || sqlType.equalsIgnoreCase("nchar")
                || sqlType.equalsIgnoreCase("clob")) {
            return "String";
        } else if (sqlType.equalsIgnoreCase("datetime") || sqlType.equalsIgnoreCase("timestamp")
                || sqlType.equalsIgnoreCase("DATE")) {
            return "Date";
        }

        return null;
    }

    public static String camelToUnderline(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append(UNDERLINE);
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 下划线转驼峰
     * @param param
     * @return
     */
    public static String underlineToCamel(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (c == UNDERLINE) {
                if (++i < len) {
                    sb.append(Character.toUpperCase(param.charAt(i)));
                }
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 去除表名字开头
     * @param param
     * @return
     */
    private String removeRcoOrRc(String param){
    	String rtl = "";
    	if(param.startsWith("RCO_")){
    		rtl = param.substring(4);
    	} else if(param.startsWith("RC_")){
    		rtl = param.substring(3);
    	}
    	return rtl;
    }

    public static String underlineToCamel2(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        StringBuilder sb = new StringBuilder(param);
        Matcher mc = Pattern.compile("_").matcher(param);
        int i = 0;
        while (mc.find()) {
            int position = mc.end() - (i++);
            // String.valueOf(Character.toUpperCase(sb.charAt(position)));
            sb.replace(position - 1, position + 1, sb.substring(position, position + 1).toUpperCase());
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        new AutoDaoTool();
    }
}